home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / session.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  10KB  |  499 lines

  1. /* NOS User Session control
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by PA0GRI
  5.  */
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "config.h"
  9. #include "mbuf.h"
  10. #include "proc.h"
  11. #include "ftpcli.h"
  12. #include "icmp.h"
  13. #include "telnet.h"
  14. #include "tty.h"
  15. #include "session.h"
  16. #include "hardware.h"
  17. #include "socket.h"
  18. #include "cmdparse.h"
  19. #include "rlogin.h"
  20. #include "commands.h"
  21. #include "main.h"
  22.  
  23. struct session *Sessions;
  24. struct session *Command;
  25. struct session *Current;
  26. struct session *Lastcurr;
  27. int Row;
  28. int Morewait;
  29. extern int Numrows;
  30.  
  31. char Notval[] = "Not a valid control block\n";
  32. static char Badsess[] = "Invalid session\n";
  33. char TooManySessions[] = "Too many sessions\n";
  34.  
  35. char *Sestypes[] = {
  36.     "", /* The command session */
  37.     "Telnet",
  38.     "FTP",
  39.     "AX25",
  40.     "Finger",
  41.     "Ping",
  42.     "NET/ROM",
  43.     "Command",
  44.     "More",
  45.     "Hopcheck",
  46.     "Tip",
  47.     "PPP PAP",
  48.     "Dial",
  49.     "Query",
  50.     "Cache",
  51.     "Rlogin",
  52.     "Repeat",
  53. #ifdef UNIX
  54.     "Trace"
  55. #else
  56.     ""  /* The trace session */
  57. #endif
  58. };
  59.  
  60. /* Convert a character string containing a decimal session index number
  61.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  62.  * If the index is out of range or unused, return NULLSESSION.
  63.  */
  64. struct session *
  65. sessptr(cp)
  66. char *cp;
  67. {
  68.     register struct session *sp;
  69.     unsigned int i;
  70.  
  71.     if(cp == NULLCHAR){
  72.         sp = Lastcurr;
  73.     } else {
  74.         i = (unsigned)atoi(cp);
  75.         if(i >= Nsessions)
  76.             sp = NULLSESSION;
  77.         else
  78.             sp = &Sessions[i];
  79.     }
  80.     if(sp == NULLSESSION || sp->type == FREE)
  81.         sp = NULLSESSION;
  82.  
  83.     return sp;
  84. }
  85.  
  86. /* Select and display sessions */
  87. int
  88. dosession(argc,argv,p)
  89. int argc;
  90. char *argv[];
  91. void *p;
  92. {
  93.     struct session *sp;
  94.     struct sockaddr fsocket;
  95.     int i,k,s;
  96.     int r,t;
  97.     char *cp;
  98.     char *param[3];
  99.  
  100.     sp = (struct session *)p;
  101. #ifdef __GNUC__
  102.     k = 0;            /* spurious warning */
  103. #endif
  104.  
  105.     if(argc > 1){
  106.         if((sp = sessptr(argv[1])) == NULLSESSION){
  107.             tprintf("Session %s not active\n",argv[1]);
  108.             return 1;
  109.         }
  110.         if(argc == 2){
  111.             go(0,NULL,sp);
  112.         }
  113.         param[0] = argv[2];
  114.         param[1] = argv[3];
  115.         param[2] = NULL;
  116.         if(argc > 2){
  117.             switch (*argv[2]) {
  118.             case 'f':    /* flowmode */
  119.                 setbool(&sp->flowmode,"Set flowmode on/off",argc-2,param);
  120.                 break;
  121.             default:
  122.                 tprintf("usage:session # [flow [on/off]]\n");
  123.             }
  124.         }
  125.         return 0;
  126.     }
  127.     tprintf(" #  S#  Type     Rcv-Q Snd-Q State        Remote socket\n");
  128.     for(sp=Sessions; sp < &Sessions[Nsessions];sp++){
  129.         if(sp->type == FREE || sp->type == COMMAND || \
  130.            sp->type == TRACESESSION)
  131.             continue;
  132.  
  133.         /* Rcv-Q includes output pending at the screen driver */
  134.         r = socklen(sp->output,1);
  135.         t = 0;
  136.         cp = NULLCHAR;
  137.         if((s = sp->s) != -1){
  138.             i = SOCKSIZE;
  139.             s = sp->s;
  140.             k = getpeername(s,(char *)&fsocket,&i);
  141.             r += socklen(s,0);
  142.             t += socklen(s,1);
  143.             cp = sockstate(s);
  144.         }
  145.         tprintf("%c", (Lastcurr == sp)? '*':' ');
  146.         tprintf("%-3u", (unsigned)(sp - Sessions));
  147.         tprintf("%-4d%-8s%6d%6d %-13s",
  148.          s,
  149.          Sestypes[sp->type],
  150.          r,
  151.          t,
  152.          (cp != NULLCHAR) ? cp : "Limbo!");
  153.         if(sp->name != NULLCHAR)
  154.             tprintf("%s ",sp->name);
  155.         if(sp->s != -1 && k == 0)
  156.             tprintf("(%s)",psocket(&fsocket));
  157.  
  158.         tprintf("\n");
  159.         if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
  160.             /* Display data channel, if any */
  161.             i = SOCKSIZE;
  162.             k = getpeername(s,(char *)&fsocket,&i);
  163.             r = socklen(s,0);
  164.             t = socklen(s,1);
  165.             cp = sockstate(s);
  166.             tprintf("    %-4d%-8s%6d%6d %-13s%s",
  167.              s,
  168.              Sestypes[sp->type],
  169.              r,
  170.              t,
  171.              (cp != NULLCHAR) ? cp : "Limbo!",
  172.              (sp->name != NULLCHAR) ? sp->name : "");
  173.             if(k == 0)
  174.                 tprintf(" (%s)",psocket(&fsocket));
  175.             if(tprintf("\n") == EOF)
  176.                 break;
  177.         }
  178.         if(sp->rfile != NULLCHAR)
  179.             tprintf("    Record: %s\n",sp->rfile);
  180.         if(sp->ufile != NULLCHAR)
  181.             tprintf("    Upload: %s\n",sp->ufile);
  182.     }
  183.     return 0;
  184. }
  185. /* Resume current session, and wait for it */
  186. int
  187. go(argc,argv,p)
  188. int argc;
  189. char *argv[];
  190. void *p;
  191. {
  192.     struct session *sp;
  193.  
  194.     sp = (struct session *)p;
  195.     if(sp == NULLSESSION || sp->type == FREE || \
  196.        sp->type == COMMAND || sp->type == TRACESESSION)
  197.         return 0;
  198.     Current = sp;
  199.     swapscreen(Command,sp);
  200.     psignal(sp,0);
  201.     return 0;
  202. }
  203. int
  204. doclose(argc,argv,p)
  205. int argc;
  206. char *argv[];
  207. void *p;
  208. {
  209.     struct session *sp;
  210.  
  211.     sp = (struct session *)p;
  212.     if(argc > 1)
  213.         sp = sessptr(argv[1]);
  214.  
  215.     if(sp == NULLSESSION){
  216.         tprintf(Badsess);
  217.         return -1;
  218.     }
  219.     shutdown(sp->s,1);
  220.     return 0;
  221. }
  222. int
  223. doreset(argc,argv,p)
  224. int argc;
  225. char *argv[];
  226. void *p;
  227. {
  228.     struct session *sp;
  229.  
  230.     sp = (struct session *)p;
  231.     if(argc > 1)
  232.         sp = sessptr(argv[1]);
  233.  
  234.     if(sp == NULLSESSION){
  235.         tprintf(Badsess);
  236.         return -1;
  237.     }
  238.     /* Unwedge anyone waiting for a domain resolution, etc */
  239.     alert(sp->proc,EABORT);
  240.     shutdown(sp->s,2);
  241.     if(sp->type == FTP)
  242.         shutdown(sp->cb.ftp->data,2);
  243.     return 0;
  244. }
  245. int
  246. dokick(argc,argv,p)
  247. int argc;
  248. char *argv[];
  249. void *p;
  250. {
  251.     struct session *sp;
  252.  
  253.     sp = (struct session *)p;
  254.     if(argc > 1)
  255.         sp = sessptr(argv[1]);
  256.  
  257.     if(sp == NULLSESSION){
  258.         tprintf(Badsess);
  259.         return -1;
  260.     }
  261.     sockkick(sp->s);
  262.     if(sp->type == FTP)
  263.         sockkick(sp->cb.ftp->data);
  264.     return 0;
  265. }
  266.  
  267. struct session *
  268. newsession(name,type,split)
  269. char *name;
  270. int type;
  271. int split;
  272. {
  273.     register struct session *sp;
  274.     int i;
  275.  
  276.     /* Reserve the highest session for Trace, so that
  277.      * the F-key session switching works correctly - WG7J
  278.      */
  279.     if(type == TRACESESSION) { /* This can only get called once !! */
  280.         i=0;
  281.         sp=Sessions;
  282.         while(i!=Nsessions-1) {
  283.             i++;
  284.             sp++;
  285.         }
  286.     } else {
  287.         for(i=0,sp=Sessions;i < Nsessions;sp++,i++)
  288.             if(sp->type == FREE)
  289.                 break;
  290.     }
  291.     if(i == Nsessions)
  292.         return NULLSESSION;
  293.  
  294.     sp->type = type;
  295.     sp->s = -1;
  296.     if(name != NULLCHAR)
  297.         sp->name = strdup(name);
  298.     sp->proc = Curproc;
  299. #ifdef UNIX
  300.     /* update Curproc's session pointer as well! */
  301.     /* (in theory this could leave a dangling session...?) */
  302.     Curproc->session = sp;
  303. #endif
  304.     /* Create standard input and output sockets. Output is
  305.      * translated to local end-of-line by default
  306.      */
  307.     Curproc->input =  sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
  308.     seteol(Curproc->input,Eol);
  309.     sockmode(Curproc->input,SOCK_BINARY);
  310.     Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
  311.     seteol(Curproc->output,Eol);
  312.     sockmode(Curproc->output,SOCK_ASCII);
  313.  
  314.     /* on by default */
  315.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  316.     sp->flowmode = 0;    /* Off by default */
  317.     sp->row = Numrows;
  318.     sp->morewait = 0;
  319.     sp->split = split;
  320.     newscreen(sp);
  321.     swapscreen(Current,sp);
  322.     Current = sp;
  323.     return sp;
  324. }
  325. void
  326. freesession(sp)
  327. struct session *sp;
  328. {
  329.     if(sp == NULLSESSION)
  330.         return;
  331.     pwait(NULL);    /* Wait for any pending output to go */
  332.     rflush();
  333.  
  334.     if(sp->proc1 != NULLPROC)
  335.         killproc(sp->proc1);
  336.     sp->proc1 = NULLPROC;
  337.     if(sp->proc2 != NULLPROC)
  338.         killproc(sp->proc2);
  339.     sp->proc2 = NULLPROC;
  340.  
  341.     free_p(sp->ttystate.line);
  342.     sp->ttystate.line = NULLBUF;
  343.     if(sp->s != -1)
  344.         close_s(sp->s);
  345.     if(sp->record != NULLFILE){
  346.         fclose(sp->record);
  347.         sp->record = NULLFILE;
  348.     }
  349.     free(sp->rfile);
  350.     sp->rfile = NULLCHAR;
  351.     if(sp->upload != NULLFILE){
  352.         fclose(sp->upload);
  353.         sp->upload = NULLFILE;
  354.     }
  355.     free(sp->ufile);
  356.     sp->ufile = NULLCHAR;
  357.     free(sp->name);
  358.     sp->name = NULLCHAR;
  359.     sp->type = FREE;
  360.  
  361.     close_s(sp->input);
  362.     sp->input = -1;
  363.     sp->proc->input = -1;
  364.     close_s(sp->output);
  365.     sp->output = -1;
  366.     sp->proc->output = -1;
  367.  
  368.     freescreen(sp);
  369.     if(Current == sp){
  370.         Current = Command;
  371.         swapscreen(NULLSESSION,Command);
  372. #ifndef UNIX
  373.         alert(Display,1);
  374. #endif
  375.     }
  376. #ifdef UNIX
  377.     /* reparent process to command session */
  378.     sp->proc->session = Command;
  379. #endif
  380.     if(Lastcurr == sp)
  381.         Lastcurr = NULLSESSION;
  382. }
  383. #ifdef ALLCMD
  384. /* Control session recording */
  385. int
  386. dorecord(argc,argv,p)
  387. int argc;
  388. char *argv[];
  389. void *p;
  390. {
  391.     struct session *sp;
  392.     char *mode;
  393.  
  394.     sp = (struct session *)p;
  395.     if(sp == NULLSESSION){
  396.         tprintf("No current session\n");
  397.         return 1;
  398.     }
  399.     if(argc > 1){
  400.         if(sp->rfile != NULLCHAR){
  401.             fclose(sp->record);
  402.             free(sp->rfile);
  403.             sp->record = NULLFILE;
  404.             sp->rfile = NULLCHAR;
  405.         }
  406.         /* Open new record file, unless file name is "off", which means
  407.          * disable recording
  408.          */
  409.         if(strcmp(argv[1],"off") != 0){
  410.             if(sockmode(sp->output,-1) == SOCK_ASCII)
  411.                 mode = APPEND_TEXT;
  412.             else
  413.                 mode = APPEND_BINARY;
  414.  
  415.             if((sp->record = fopen(argv[1],mode)) == NULLFILE)
  416.                 tprintf("Can't open %s: %s\n",argv[1],sys_errlist[errno]);
  417.             else
  418.                 sp->rfile = strdup(argv[1]);
  419.         }
  420.     }
  421.     if(sp->rfile != NULLCHAR)
  422.         tprintf("Recording into %s\n",sp->rfile);
  423.     else
  424.         tprintf("Recording off\n");
  425.     return 0;
  426. }
  427. /* Control file transmission */
  428. int
  429. doupload(argc,argv,p)
  430. int argc;
  431. char *argv[];
  432. void *p;
  433. {
  434.     register struct session *sp;
  435.  
  436.     sp = (struct session *)p;
  437.     if(sp == NULLSESSION){
  438.         tprintf("No current session\n");
  439.         return 1;
  440.     }
  441.     if(argc < 2){
  442.         if(sp->ufile != NULLCHAR)
  443.             tprintf("Uploading %s\n",sp->ufile);
  444.         else
  445.             tprintf("Uploading off\n");
  446.         return 0;
  447.     }
  448.     if(strcmp(argv[1],"stop") == 0 && sp->upload != NULLFILE){
  449.         /* Abort upload */
  450.         fclose(sp->upload);
  451.         sp->upload = NULLFILE;
  452.         free(sp->ufile);
  453.         sp->ufile = NULLCHAR;
  454.         killproc(sp->proc2);
  455.         sp->proc2 = NULLPROC;
  456.         return 0;
  457.     }
  458.     /* Open upload file */
  459.     if((sp->upload = fopen(argv[1],READ_TEXT)) == NULLFILE){
  460.         tprintf("Can't read %s: %s\n",argv[1],sys_errlist[errno]);
  461.         return 1;
  462.     }
  463.     sp->ufile = strdup(argv[1]);
  464.     /* All set, invoke the upload process */
  465.     sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  466.     return 0;
  467. }
  468. /* File uploading task */
  469. void
  470. upload(unused,sp1,p)
  471. int unused;
  472. void *sp1;
  473. void *p;
  474. {
  475.     struct session *sp;
  476.     int oldf;
  477.     char *buf;
  478.  
  479.     sp = (struct session *)sp1;
  480.  
  481.     /* Disable newline buffering for the duration */
  482.     oldf = setflush(sp->s,-1);
  483.  
  484.     buf = mallocw(BUFSIZ);
  485.     while(fgets(buf,BUFSIZ,sp->upload) != NULLCHAR)
  486.         if(usputs(sp->s,buf) == EOF)
  487.             break;
  488.  
  489.     free(buf);
  490.     usflush(sp->s);
  491.     setflush(sp->s,oldf);
  492.     fclose(sp->upload);
  493.     sp->upload = NULLFILE;
  494.     free(sp->ufile);
  495.     sp->ufile = NULLCHAR;
  496.     sp->proc2 = NULLPROC;
  497. }
  498. #endif /*ALLCMD*/
  499.